package java8.stream.demo01;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static java.util.Comparator.comparing;
import static java.util.Comparator.comparingInt;
import static java.util.stream.Collectors.toList;

/**
 * @author ChangLiang
 * @date 2020/4/22
 */
public class DishService {

    private static final Logger logger = LoggerFactory.getLogger(DishService.class);

    public static List<String> getDishNamesWithStreamLog(List<Dish> menu) {
        return menu.stream().filter(d -> {
            logger.info("filtering->{}" , d.getName());
            return d.getCalories() > 300;
        })
                .map(d -> {
                    logger.info("map->{}", d.getName());
                    return d.getName();
                })
                .limit(3)
                .collect(toList());
    }

    public static List<String> getDishNamesByStreamParallel(List<Dish> menu) {
        List<String> names = menu.parallelStream().filter(dish -> {
            logger.info("filtering->{}" , dish.getName());
            // test if parallel execute
/*            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }*/
            return dish.getCalories() < 400;
        })
                .sorted(comparing(Dish::getCalories))
                .map(d -> {
                    logger.info("map->{}", d.getName());
                    return d.getName();
                })
                .collect(toList());
        return names;
    }


    public static List<String> getDishNamesByStream(List<Dish> menu) {
        List<String> names = menu.stream().filter(dish -> dish.getCalories() < 400)
                .sorted(comparing(Dish::getCalories))
                .map(Dish::getName)
                .collect(toList());
        return names;
    }

    /**
     * calories < 400 and order by calories desc
     * @param menu
     * @return
     */
    public static List<String> getDishNamesByCollections(List<Dish> menu) {
        List<Dish> lowCalories = new ArrayList<>();
        // filter and get calories less 400
        for (Dish d : menu) {
            if (d.getCalories() < 400) {
                lowCalories.add(d);
            }
        }
        // sort
        Collections.sort(lowCalories, comparingInt(Dish::getCalories));
        // filter and get result
        List<String> dishNameList = new ArrayList<>();
        for (Dish d : lowCalories) {
            dishNameList.add(d.getName());
        }
        return dishNameList;
    }
}
